package store

import (
	"sort"

	"file_explorer/model"
	"file_explorer/service/eventbus"
)

type OpListContext struct {
	DefaultTabContext

	FileInfos   []*model.FileInfo // 操作文件列表
	CheckedList []*model.FileInfo // 选中文件列表

	sortFunc func(a, b *model.FileInfo) bool
}

func (ctx *OpListContext) SetSortFunc(cmp func(a, b *model.FileInfo) bool) {
	ctx.sortFunc = cmp
	sort.Slice(ctx.FileInfos, func(i, j int) bool {
		return ctx.sortFunc(ctx.FileInfos[i], ctx.FileInfos[j])
	})
}

func (ctx *OpListContext) SetFileInfos(fileInfos []*model.FileInfo) {
	if ctx.sortFunc != nil {
		sort.Slice(fileInfos, func(i, j int) bool {
			return ctx.sortFunc(fileInfos[i], fileInfos[j])
		})
	}
	ctx.FileInfos = fileInfos
	ctx.ProduceEvent(eventbus.EventKeyOpListCtxFileChange, nil)
}

func (ctx *OpListContext) AddFileInfos(fileInfos []*model.FileInfo) {
	pathFileInfoMap := make(map[string]*model.FileInfo)
	for _, fileInfo := range fileInfos {
		pathFileInfoMap[fileInfo.GetPath()] = fileInfo
	}
	for _, fileInfo := range ctx.FileInfos {
		pathFileInfoMap[fileInfo.GetPath()] = fileInfo
	}
	fileInfos = make([]*model.FileInfo, 0, len(pathFileInfoMap))
	for _, fileInfo := range pathFileInfoMap {
		fileInfos = append(fileInfos, fileInfo)
	}

	ctx.CheckedList = append(ctx.CheckedList, fileInfos...)
	ctx.SetFileInfos(fileInfos)
}

func (ctx *OpListContext) DeleteFileInfos(fileInfos []*model.FileInfo) {
	pathFileInfoMap := make(map[string]*model.FileInfo)
	for _, fileInfo := range fileInfos {
		pathFileInfoMap[fileInfo.GetPath()] = fileInfo
	}

	newOpFileInfos := make([]*model.FileInfo, 0, len(ctx.FileInfos))
	newCheckedList := make([]*model.FileInfo, 0, len(ctx.CheckedList))
	for _, fileInfo := range ctx.FileInfos {
		if _, ok := pathFileInfoMap[fileInfo.GetPath()]; !ok {
			newOpFileInfos = append(newOpFileInfos, fileInfo)
		}
	}
	for _, fileInfo := range ctx.CheckedList {
		if _, ok := pathFileInfoMap[fileInfo.GetPath()]; !ok {
			newCheckedList = append(newCheckedList, fileInfo)
		}
	}

	ctx.CheckedList = newCheckedList
	ctx.ProduceEvent(eventbus.EventKeyOpListCtxChecklistChange, nil)
	ctx.SetFileInfos(newOpFileInfos)
}

func NewOpListContext(gCtx *GlobalContext) *OpListContext {
	return &OpListContext{
		DefaultTabContext: newDefaultTabContext(gCtx),
	}
}
